package mutex

import (
	"fmt"
	"sync"
	"time"
)

// 没有锁
var tickets = 100

func MutexDemoFirst() {
	for i := 0; i < 10; i++ {
		go func(i int) {
			for tickets > 0 {
				ticket.num--
				fmt.Printf("第%d号窗口,现在还有%d张票\n", i, ticket.num)
				time.Sleep(time.Millisecond)
			}
		}(i)
	}

	time.Sleep(time.Second)
}

type Ticket struct {
	num int
	sync.Mutex
}

var ticket = Ticket{num: 100}

func MutexDemoLock() {
	for i := 0; i < 10; i++ {
		go func(i int) {
			for ticket.num > 0 {
				ticket.Lock()
				ticket.num--
				fmt.Printf("第%d号窗口,现在还有%d张票\n", i, ticket.num)
				ticket.Unlock()
				time.Sleep(time.Millisecond)
			}
		}(i)
	}

	time.Sleep(time.Second)
}

func MutexDemoRightLock() {
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
				ticket.Lock()
				if ticket.num > 0 {
					ticket.num--
					fmt.Printf("第%d号窗口,现在还有%d张票\n", i, ticket.num)
				}
				ticket.Unlock()
				time.Sleep(time.Millisecond)
			}
		}(i)
	}
}

type atomicInt struct {
	value int
	lock  sync.Mutex
}

func (a *atomicInt) increment() {
	fmt.Println("safe increment")
	func() {
		a.lock.Lock()
		defer a.lock.Unlock()

		a.value++
	}()
}

func (a *atomicInt) get() int {
	a.lock.Lock()
	defer a.lock.Unlock()

	return a.value
}

// 简单实现用channel卖票
type Tickets struct {
	num  chan int
	done chan bool
}

func ChannelModifyTickts() {
	tickets := Tickets{make(chan int), make(chan bool)}
	for i := 0; i < 10; i++ {
		go func(id int, tickets Tickets) {
			for {
				num := <-tickets.num
				if num > 0 {
					num--
					fmt.Printf("第%d号窗口,现在还有%d张票\n", id, num)
					tickets.num <- num
					tickets.done <- true
				} else {
					close(tickets.done)
				}
			}
		}(i, tickets)
	}
	tickets.num <- 100
	for range tickets.done {
		//fmt.Println(done)
	}
}
